﻿using System;
using System.Collections.Generic;

/*
    Compare.Net
    Nicholas Bambury 
    Created October 2011.

    Compare.Net is a configurable application to compare and reconclie from different sources

    Licence - Microsoft  Public Licence. See http://dbasereader.codeplex.com/license for details.
 
*/

namespace Compare.Net
{
    /// <summary>
    /// File Type Enum
    /// 
    /// cvsFile = 1
    /// tabFile = 2,
    /// flatFile = 3
    /// </summary>
    enum FileType
    {
        csvFile = 1,
        tabFile = 2,
        flatFile = 3
    };

    class InputFile
    {
        private FileType m_fileType;
        private int m_fieldCount;
        private int m_recordCount;
        private String m_FileName;
        private String m_Path;

        private SortedList<int, List<String>> fileData;
        private List<String> recordData;

        private Byte[] fileBuffer;

        /// <summary>
        /// Private SplitFileNameAndPath
        /// </summary>
        /// <param name="fileNameToSplit"></param>
        /// <param name="fileName"></param>
        /// <param name="path"></param>
        /// <returns></returns>
        private bool SplitFileNameAndPath(string fileNameToSplit, out string fileName, out string path)
        {
            try
            {
                int pos = fileNameToSplit.LastIndexOf('\\');

                path = fileNameToSplit.Substring(0, pos);
                fileName = fileNameToSplit.Substring(pos + 1);

                return true;
            }
            catch (ArgumentOutOfRangeException ex_AOOR)
            {
                fileName = null;
                path = null;

                return false;
            }
            catch (Exception ex)
            {
                fileName = null;
                path = null;

                return false;
            }
        }

        /// <summary>
        /// Private ReadInputDataFile
        /// </summary>
        /// <returns></returns>
        private bool ReadInputDataFile()
        {
            try
            {
                if (m_fileType == FileType.csvFile)
                {
                    String[] temp = System.IO.File.ReadAllLines(m_Path +"\\" +m_FileName);

                    if (!SeperateOutData(temp))
                    {
                        System.Windows.MessageBox.Show("Can not Split Input Data into records", "ReadInputDataFile Error", System.Windows.MessageBoxButton.OK, System.Windows.MessageBoxImage.Error);
                    }
                }
                else if (m_fileType == FileType.flatFile)
                {
                    using (System.IO.FileStream fs = new System.IO.FileStream(m_Path + "\\" + m_FileName, System.IO.FileMode.Open))
                    {
                        fileBuffer = new byte[fs.Length];

                        fs.Read(fileBuffer, 0, (int)fs.Length);
                    }
                }

                return true;
            }
            catch (System.IO.IOException ex_IO)
            {
                return false;
            }

            catch (Exception ex)
            {
                return false;
            }
        }

        /// <summary>
        /// Private SeperateOutData
        /// 
        /// Used to seperate comma or tab dilimited data.
        /// </summary>
        /// <param name="lineDataArray"></param>
        /// <returns></returns>
        private bool SeperateOutData(String[] lineDataArray)
        {
            try
            {
                fileData = new SortedList<int, List<string>>();
                m_recordCount = 1;

                foreach (string lineData in lineDataArray)
                {
                    String[] temp = null;
                    if (m_fileType==FileType.csvFile)
                        temp = lineData.Split(',');
                    else if (m_fileType==FileType.tabFile)
                        temp = lineData.Split('\t');

                    m_fieldCount = temp.Length;

                    recordData = new List<string>();
                    recordData.AddRange(temp);          // Converts String[] to a List<string>

                    fileData.Add(m_recordCount, recordData);    // Adds List<string> to SortedList

                    m_recordCount++;
                }

                m_recordCount--;    // Reduced by 1 to give correct record count (Because of loop above)

                return true;
            }
            catch (Exception ex)
            {
                m_fieldCount = 0;
                m_recordCount = 0;
                recordData = null;
                fileData = null;
                return false;
            }
        }

        /// <summary>
        /// Public InputFile Constructor
        /// </summary>
        /// <param name="inputFile"></param>
        /// <param name="input_fileType"></param>
        public InputFile(string inputFile, FileType input_fileType)
        {
            try
            {
                m_fileType = input_fileType;

                if (SplitFileNameAndPath(inputFile, out m_FileName, out m_Path))
                {
                    if (!ReadInputDataFile())
                    {
                        System.Windows.MessageBox.Show("Can not read Input File", "InputFile Error", System.Windows.MessageBoxButton.OK, System.Windows.MessageBoxImage.Exclamation);
                    }
                }
                else
                {
                    System.Windows.MessageBox.Show("Can not open Input File", "InputFile Error", System.Windows.MessageBoxButton.OK, System.Windows.MessageBoxImage.Exclamation);
                }
            }
            catch (Exception ex)
            {
                System.Windows.MessageBox.Show(ex.Message, "InputFile Exception", System.Windows.MessageBoxButton.OK, System.Windows.MessageBoxImage.Error);
            }
        }        
    }
}
